import React from "react";
import {TreeSelect as AntTreeSelect} from "antd";

import BaseComponent from "../BaseComponent";

export default class TreeSelect extends BaseComponent {

    static defaultProps = {
        _treeDataSelectableFun: undefined,
        _treeDataCheckableFun: undefined,
        _treeDataDisableCheckboxFun: undefined,
        _treeDataDisabledFun: undefined,
        _treeDataIsLeafFun: undefined,
        _treeDataKeyFun: undefined,
        _treeDataTitleFun: undefined,
        _treeDataValueFun: undefined,
        _treeDataChildrenFun: undefined,
        _simpleTreeDataIdFun: undefined,
        _simpleTreeDataPidFun: undefined
    };

    constructor(props) {
        super(props);
        this._treeData = this._wrapperTreeData(this.props.treeData);
    }

    UNSAFE_componentWillReceiveProps({treeData}, nextContext) {
        if (this.props.treeData !== treeData) {
            this.setTreeData(treeData);
        }
    }

    setTreeData(data) {
        this._treeData = this._wrapperTreeData(data);
        this.refreshState();
    }

    _wrapperTreeData(data) {
        if (!(data instanceof Array)) {
            return [];
        }
        return this._wrapperData(data);
    }

    _wrapperData(data) {
        let _data = [];
        let {treeDataSimpleMode, _simpleTreeDataIdFun, _simpleTreeDataPidFun, _treeDataSelectableFun, _treeDataCheckableFun, _treeDataDisableCheckboxFun, _treeDataDisabledFun, _treeDataIsLeafFun, _treeDataKeyFun, _treeDataTitleFun, _treeDataValueFun, _treeDataChildrenFun} = this.props;
        data.forEach(d => {
            let _d = {...d};
            if (_treeDataSelectableFun) {
                _d.selectable = _treeDataSelectableFun(d);
            }
            if (_treeDataCheckableFun) {
                _d.checkable = _treeDataCheckableFun(d);
            }
            if (_treeDataDisableCheckboxFun) {
                _d.disableCheckbox = _treeDataDisableCheckboxFun(d);
            }
            if (_treeDataDisabledFun) {
                _d.disabled = _treeDataDisabledFun(d);
            }
            if (_treeDataKeyFun) {
                _d.key = _treeDataKeyFun(d);
            }
            if (_treeDataValueFun) {
                _d.value = _treeDataValueFun(d);
            }
            if (_treeDataTitleFun) {
                _d.title = _treeDataTitleFun(d);
            }
            if (treeDataSimpleMode) {
                if (_simpleTreeDataIdFun) {
                    _d.id = _simpleTreeDataIdFun(d);
                }
                if (_simpleTreeDataPidFun) {
                    _d.pId = _simpleTreeDataPidFun(d);
                }
            } else {
                if (_treeDataIsLeafFun) {
                    _d.isLeaf = _treeDataIsLeafFun(d);
                }
                if (_treeDataChildrenFun) {
                    _d.children = _treeDataChildrenFun(d);
                }
                if (_d.children && _d.children instanceof Array && _d.children.length === 0) {
                    _d.isLeaf = true;
                }
                if (_d.children instanceof Array) {
                    _d.children = this._wrapperData(_d.children);
                } else {
                    delete _data.children;
                }
            }
            _data.push(_d);
        });
        return _data;
    }

    _findDataByValue(data, value) {
        if (!(data instanceof Array)) {
            return null;
        }
        for (let i = 0; i < data.length; i++) {
            let d = data[i];
            if (value === d.value) {
                return d;
            }
            if (d.children) {
                d = this._findDataByValue(d.children, value);
                if (d) {
                    return d;
                }
            }
        }
        return null;
    }

    _loadData(node) {
        return new Promise(resolve => {
            this.props.loadData(node.props, (data) => {
                let {treeDataSimpleMode} = this.props;
                data = this._wrapperTreeData(data);
                if (treeDataSimpleMode) {
                    this._treeData.push(...data);
                } else {
                    let nodeData = this._findDataByValue(this._treeData, node.props.value);
                    if (nodeData) {
                        nodeData.children = data;
                    }
                }
                this.refreshState();
                resolve();
            });
        });
    }

    _parseProps() {
        let options = {};
        Object.keys(this.props || {}).forEach(key => {
            if (key.indexOf('_') === 0) {
                return;
            }
            options[key] = this.props[key];
        });
        return options;
    }

    render() {

        let options = this._parseProps();

        options.treeData = this._treeData;
        if (this.props.loadData) {
            options.loadData = this._loadData.bind(this);
        }
        return (
            <AntTreeSelect {...options}>
                {this.props.children}
            </AntTreeSelect>
        )
    }
}

TreeSelect.TreeNode = AntTreeSelect.TreeNode;
TreeSelect.SHOW_ALL = AntTreeSelect.SHOW_ALL;
TreeSelect.SHOW_PARENT = AntTreeSelect.SHOW_PARENT;
TreeSelect.SHOW_CHILD = AntTreeSelect.SHOW_CHILD;
